//-------------------------------------------------------------------------
/**
   File:   RegistryKey.h

   Descr.: - todo -

   Author: Stefan Leihkauf
   Date:   8/8/2011
*/
//-------------------------------------------------------------------------
#ifndef _REGISTRYKEY_H
#define _REGISTRYKEY_H
#include "flagset.hpp"
#include "registry/RegistryTypes.h"
#include "registry/RegistryValue.h"

class RegistryKey
{
	/* instances are created by one of the Registry static methods */
	friend class Registry;

public:

	/* registry key access rights */
	enum AccessRight {
		Read 	  = KEY_READ,
		Write 	  = KEY_WRITE,
		ReadWrite = KEY_READ | KEY_WRITE
	};
	/* type holding registry key access rights */
	typedef flagset<AccessRight> AccessRights;

	/* type of subkey namelist */
	typedef std::vector<StdString> SubKeyNameList;

	/* type of key values list */
	typedef std::vector<RegistryValue> KeyValueList;

	/* some limits */
	static unsigned const MaxKeyName	/*= 255*/;
	static unsigned const MaxValueName	/*= 16383*/;

protected:
	/// constructor
	RegistryKey(WinHKey handle, const StdString& name);

public:
	/// destructor
	~RegistryKey();

	/// get keyname
	const StdString& Name() const;
	/// get key values
	const KeyValueList& Values() const;

	/// get subkeynames
	const SubKeyNameList& SubKeyNames() const;
	/// close key
	void Close();

	/// open an subkey
	RegistryKey OpenSubKey(const StdString& name, const RegistryKey::AccessRights = RegistryKey::Read) const;
	/// create an subkey
	RegistryKey CreateSubKey(const StdString& name, const RegistryKey::AccessRights accessRights = RegistryKey::Write);

	/// check if valid
	inline bool isValid() const {
		return (*this == true);
	}

	/// boolean operator
	inline operator bool () const {
		return (_hkey == true); // implicit conversion to bool
	}

private:
	void EnumSubkeyNames();
	void EnumKeyValues();

	WinHKey _hkey; // reference counted handle
	StdString _name; // name of registry key

	/* subkeynames are once enumerated during the construction of the object
	*/
	SubKeyNameList _subkeynames;

	/* list of values belonging to this key
	*/
	KeyValueList _keyvalues;
};
#endif //!defined _REGISTRYKEY_H